package ai.esc.speedy.admin.user.domain.aggregate;

import ai.esc.speedy.admin.user.api.*;
import ai.esc.speedy.common.util.id.UIDGenerator;
import ai.esc.speedy.common.valueobject.Extend;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.eventsourcing.EventSourcingHandler;
import org.axonframework.modelling.command.AggregateIdentifier;
import org.axonframework.spring.stereotype.Aggregate;

import static org.axonframework.modelling.command.AggregateLifecycle.apply;

/**
 * @author Rubin
 * @version v1 2020/3/3 15:37
 */
@Aggregate
public class AppUserAggregate {

    @AggregateIdentifier
    private String userId;

    private AppUser appUser;
    private Passport passport;

    public AppUserAggregate() {
    }

    /**
     * 构造函数里的匹配是聚合的开始，它设定了聚合ID，后者通过聚合ID来到这里
     *
     * @param command
     */
    @CommandHandler
    public AppUserAggregate(CreateAppUserCommand command) {
        this.userId = command.getUserId();
        this.appUser = new AppUser(userId);
        this.appUser.setData(new Extend(command.getData().toJSONString()));

        BeanUtil.copyProperties(command, appUser,
                CopyOptions.create().ignoreNullValue().setIgnoreProperties("data"));
        // ####
        Passport passport = new Passport();
        passport.setAccount(command.getPhone());

        // 手动注册，需要设置密码
        String encryptionPassword = command.getEncryptionPassword();
        if (encryptionPassword != null) {
            // 解密... 加密...
            String salt = passport.getSalt();
            passport.setSaltPassword(salt + encryptionPassword);
        }
        apply(new CreateAppUserEvent(appUser, passport));

    }

    @CommandHandler
    public void on(UpdateAppUserDataCommand command) {
        this.userId = command.getUserId();
        this.appUser = new AppUser(userId);
        this.appUser.setData(new Extend(command.getData().toJSONString()));

        Passport passport = new Passport();
        apply(new UpdateAppUserEvent(appUser, passport));
    }

    @EventSourcingHandler
    public void on(CreateAppUserEvent event) {
        this.appUser = event.getAppUser();
        this.passport = event.getPassport();
        this.userId = appUser.getUserId();

        System.out.println("创建事件（聚合）=> " + userId);
    }

    @EventSourcingHandler
    public void on(UpdateAppUserEvent event) {
        this.appUser = event.getAppUser();
        this.passport = event.getPassport();
        this.userId = appUser.getUserId();
        System.out.println("更新事件（聚合）=> " + userId);
    }

}
